/*
 * $Author: isan.wong@gmail.com $
 * $Date: 2011-07-29 01:03:06 +0000 (Fri, 29 Jul 2011) $
 * $Rev: 13 $
 * $URL: http://capitalbio-smd.googlecode.com/svn/src/com/capitalbio/smd/gui/AlignmentPane.java $
 */

package com.capitalbio.smd.gui;

import java.awt.Dimension;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.EmptyBorder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.biojava.bio.symbol.Symbol;
import org.biojava.bio.symbol.SymbolList;

import com.capitalbio.smd.base.Sample;
import com.capitalbio.smd.base.Util;

/**
 * 样品面板
 * @author Wang Lei
 */
public class AlignmentPane extends JScrollPane {
	private static final long serialVersionUID = 1L;
	protected Log log = LogFactory.getLog(this.getClass());
	
	private static final int alignmentButtonWidth = 12;
	private static final int alignmentButtonHeight = 18;
	
	private Sample sample;
	private List<AlignmentButton> alignmentButtons;

	public AlignmentPane() {
		setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
		setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
		setBorder(new EmptyBorder(0, 0, 0, 0));
		getViewport().setPreferredSize(new Dimension(0, alignmentButtonHeight * 3));
	}
	
	/**
	 * 比对标签
	 * @param sequences 第一条序列应为标准序列
	 * @return
	 */
	private JLabel getAlignmentButtonsLabel(List<SymbolList> sequences) {
		
		if (sequences == null || sequences.size() < 3) {
			return null;
		}
		
		//检查长度
		int length = sequences.get(0).length();
		for (int i = 1; i < sequences.size(); i++) {
			if (sequences.get(i).length() != length) {
				throw new IllegalArgumentException("Sequences have different length.");
			}
		}
		
		JLabel alignmentButtonsLabel = new JLabel();
		alignmentButtonsLabel.setLayout(null);
		alignmentButtonsLabel.setPreferredSize(new Dimension(length * alignmentButtonWidth, sequences.size() * alignmentButtonHeight + 1));
		
		/**
		 * 标准序列的按钮
		 */
		SymbolList sequence0 = sequences.get(0);
		for (int i = 0; i < length; i++) {
			Symbol symbol = sequence0.symbolAt(i + 1);
			AlignmentButton button = new AlignmentButton(symbol, false, false);
			button.setName("alignment_button_0_" + i);
			
			if (!symbol.equals(Util.getGapSymbol())) {
				button.setToolTipText(String.valueOf(sample.getResult().getOffset() + i));
			}
			
			button.setBounds(
				alignmentButtonWidth * i, 0,
				alignmentButtonWidth, alignmentButtonHeight
			);
			alignmentButtonsLabel.add(button);
		}
		
		/**
		 * 测序结果的两条链的按钮
		 */
		for (int j = 1; j < sequences.size(); j++) {
			int k = 0;
			for (int i = 0; i < length; i++) {
				Symbol symbol0 = sequence0.symbolAt(i + 1);
				Symbol symbol = sequences.get(j).symbolAt(i + 1);
				
				boolean highlight = ! Util.symbolsIdentity(symbol, symbol0);
				boolean enabled = true;
				if (symbol == Util.getGapSymbol()) {
					enabled = false;
				}
				
				AlignmentButton button = new AlignmentButton(symbol, highlight, enabled);
				button.setName("alignment_button_" + j + "_" + i);
				alignmentButtons.add(button);
				
				//非 gap 碱基索引
				if (symbol != Util.getGapSymbol()) {
					button.setIndex(k);
					k ++;
				}
				
				// 设置位置及大小
				button.setBounds(
					alignmentButtonWidth * i,
					alignmentButtonHeight * j,
					alignmentButtonWidth,
					alignmentButtonHeight
				);
				alignmentButtonsLabel.add(button);
			}
		}
		
		return alignmentButtonsLabel;
	}

	public void setSample(Sample sample) {
		this.sample = sample;
		
		if (sample.getStatus() == Sample.STATUS_ANALYZED_SUCCESS
				|| sample.getStatus() == Sample.STATUS_OPTIMIZED_SUCCESS) {
			alignmentButtons = new ArrayList<AlignmentButton>();
			
			List<SymbolList> sequences = new ArrayList<SymbolList>();
			SymbolList seq0 = sample.getResult().getSeq0();
			sequences.add(seq0);
			sequences.add(sample.getResult().getSeq1());
			sequences.add(sample.getResult().getSeq2());
			
			JLabel alignmentButtonsLabel = getAlignmentButtonsLabel(sequences);
			setViewportView(alignmentButtonsLabel);
		}
		else {
			setViewportView(null);
		}
	}
	
	public Sample getSample() {
		return sample;
	}

	public List<AlignmentButton> getAlignmentButtons() {
		return alignmentButtons;
	}

}
